import { bodyClass, bodyInnerHTML, closeClass, enlargeClass, imgBoxClass, imgClass, imgShadeClass, leftClass, leftCtrlClass, loadingClass, nameClass, photosScrollClass, refreshClass, resizeClass, rightClass, rightCtrlClass, rotateLeftClass, rotateRightClass, zoomInClass, zoomOutClass } from "utils/constant";
import { addClass, css, find, hide, removeClass, show } from "utils/dom"


export default class HcRender {

  $html = document.documentElement;
  /** 最外层容器 */
  $photosBody: HTMLElement
  /** 负责滚动条的容器 */
  $photosScroll: HTMLElement
  /** 逆时针旋转按钮 */
  $rotateLeft: HTMLElement
  /** 顺时针旋转按钮 */
  $rotateRight: HTMLElement
  /** 放大按钮 */
  $zoomIn: HTMLElement
  /** 缩小按钮 */
  $zoomOut: HTMLElement
  /** 图片容器 */
  $imgBox: HTMLElement
  /** 图片遮罩层 */
  $imgShade: HTMLElement
  /** 图片 */
  $img: HTMLElement
  /** 刷新按钮 */
  $refresh: HTMLElement
  /** 关闭按钮 */
  $close: HTMLElement
  /** 上一张按钮 */
  $left: HTMLElement
  /** 下一张按钮 */
  $right: HTMLElement
  /** 顶部文件名 */
  $name: HTMLElement
  /** 左上角控制组件 */
  $leftCtrl: HTMLElement
  /** 右上角控制组件 */
  $rightCtrl: HTMLElement

  htmlOverflow: string

  deg: number;
  zoom: number;

  oldProp: {
    x: number, y: number,
    width?: number, height?: number
  } = null;
  $enlarge: HTMLElement;
  $resize: HTMLElement;
  windowHeight: number;
  windowWidth: number;

  /** 初始化hcPhotos 模板 */
  initHcPhotos() {
    this.$photosBody = document.createElement("div");
    const $photosBody = this.$photosBody;
    addClass($photosBody, bodyClass);
    $photosBody.innerHTML = bodyInnerHTML;

    this.$photosScroll = find($photosBody, photosScrollClass);
    this.$imgBox = find($photosBody, imgBoxClass);
    this.$imgShade = find($photosBody, imgShadeClass);
    this.$img = find($photosBody, imgClass);
    this.$rotateLeft = find($photosBody, rotateLeftClass);
    this.$rotateRight = find($photosBody, rotateRightClass);
    this.$left = find($photosBody, leftClass);
    this.$right = find($photosBody, rightClass);
    this.$refresh = find($photosBody, refreshClass);
    this.$zoomIn = find($photosBody, zoomInClass);
    this.$zoomOut = find($photosBody, zoomOutClass);
    this.$leftCtrl = find($photosBody, leftCtrlClass);
    this.$rightCtrl = find($photosBody, rightCtrlClass);
    this.$close = find($photosBody, closeClass);
    this.$name = find($photosBody, nameClass);
    this.$enlarge = find($photosBody, enlargeClass);
    this.$resize = find($photosBody, resizeClass);

    hide(this.$refresh);
    hide(this.$enlarge);
    hide($photosBody);

    this.windowWidth = window.innerWidth;
    this.windowHeight = window.innerHeight;
    window.addEventListener("resize", () => {
      this.windowWidth = window.innerWidth;
      this.windowHeight = window.innerHeight;
    })
    document.body.append($photosBody)
  }

  /**
   * 打开预览组件
   * @param {number} len this.settings.data.length
   */
  openHcPhotos(len: number) {
    if (len === 1) {
      this.hideLR()
    } else {
      this.showLR()
    }
    show(this.$photosBody);
    this.htmlOverflow = css(this.$html, 'overflow') as string;
    css(this.$html, 'overflow', 'hidden')
  }

  move(el: HTMLElement, e: any) {
    if (el === this.$photosBody) {
      this.moveWrap(e);
    } else {
      this.moveImg(e);
    }
  }

  moveWrap(e) {
    if (!this.oldProp) {
      this.oldProp = {
        x: e.clientX,
        y: e.clientY,
      };
      return;
    }

    let xKey = "right";
    let yKey = "bottom";
    let xClac = e.clientX - this.oldProp.x;
    let yClac = e.clientY - this.oldProp.y;
    const x = parseFloat(css(this.$photosBody, xKey) as string) || 0;
    const y = parseFloat(css(this.$photosBody, yKey) as string) || 0;
    const xGap = this.windowWidth - parseInt(css(this.$photosBody, "width") as string);
    const yGap = this.windowHeight - parseInt(css(this.$photosBody, "height") as string);

    css(this.$photosBody, xKey, `${Math.max(Math.min(x - xClac, xGap), 0)}px`);
    css(this.$photosBody, yKey, `${Math.max(Math.min(y - yClac, yGap), 0)}px`);

    this.oldProp = {
      x: e.clientX,
      y: e.clientY,
    };
  }

  moveImg(e) {
    if (!this.oldProp) {
      this.oldProp = {
        x: e.clientX,
        y: e.clientY,
      };
      return;
    }
    let xKey = "left";
    let yKey = "top";
    const x = parseFloat(css(this.$imgBox, xKey) as string) || 0;
    const y = parseFloat(css(this.$imgBox, yKey) as string) || 0;
    let xClac = e.clientX - this.oldProp.x;
    let yClac = e.clientY - this.oldProp.y;

    css(this.$imgBox, xKey, `${x + xClac}px`);
    css(this.$imgBox, yKey, `${y + yClac}px`);

    this.oldProp = {
      x: e.clientX,
      y: e.clientY,
    };
  }

  resetMove(el) {
    this.oldProp = null;
    show(el === this.$imgShade ? this.$refresh : this.$enlarge);
  }

  resize(e: MouseEvent) {
    if (!this.oldProp) {
      this.oldProp = {
        x: e.clientX,
        y: e.clientY,
        width: parseInt(css(this.$photosBody, "width") as string),
        height: parseInt(css(this.$photosBody, "height") as string),
      };
      return;
    }

    css(this.$photosBody, "width", `${this.oldProp.width - (e.clientX - this.oldProp.x)}px`);
    css(this.$photosBody, "height", `${this.oldProp.height - (e.clientY - this.oldProp.y)}px`);
  }

  hideLR() {
    hide(this.$left);
    hide(this.$right);
  }

  showLR() {
    show(this.$left)
    show(this.$right)
  }

  refreshWrap() {
    css(this.$photosBody, "width", null);
    css(this.$photosBody, "height", null);
    css(this.$photosBody, "right", null);
    css(this.$photosBody, "bottom", null);
    hide(this.$enlarge);
  }

  refreshImg() {
    this.resetImg();
    hide(this.$refresh);
  }

  /** 关闭预览组件 */
  closeHcPhotos() {
    if (css(this.$photosBody, "display") === "none") {
      return;
    }
    hide(this.$photosBody);
    this.refreshWrap();
    this.refreshImg();
    css(this.$html, 'overflow', this.htmlOverflow);
  }

  /** 加载图片前 */
  beforeLoadImg() {
    css(this.$imgBox, 'width', null);
    css(this.$imgBox, 'height', null);
    addClass(this.$photosBody, loadingClass);
  }

  /** 图片加载完成 */
  afterLoadImg(e) {
    var nw = e.target.naturalWidth
    var nh = e.target.naturalHeight

    css(this.$imgBox, 'width', nw)
    css(this.$imgBox, 'height', nh)
    removeClass(this.$photosBody, loadingClass)
  }

  /** 旋转图片 */
  rotate(deg) {
    this.deg = deg;
    this.transform();
    show(this.$refresh);
  }

  /** 放大图片 */
  scale(zoom: number) {
    this.zoom = zoom;
    this.transform();
    show(this.$refresh);
  }

  transform() {
    let style = "";
    if (this.deg !== 0 && this.deg != null) {
      style += ` rotate(${this.deg}deg)`;
    }
    if (this.zoom !== 1 && this.zoom != null) {
      style += ` scale(${Math.max(this.zoom, 0)})`;
    }

    css(this.$imgBox, 'transform', style);
  }

  /** 重置图片样式 */
  resetImg() {
    css(this.$imgBox, "top", null);
    css(this.$imgBox, "left", null);
    css(this.$imgBox, 'width', null)
    css(this.$imgBox, 'height', null)
    this.zoom = 1;
    this.deg = 0;
    this.transform();
  }

}